if (m_nRecvBufferPos || m_RecvLineBuffer.size() ) {
Send(_T("503 Bad sequence of commands. Received additional data after the AUTH command before this reply could be sent."));
ForceClose(-1);
break;
}
if (m_pGssLayer)
{
Send(_T("534 Authentication type already set to GSSAPI"));
break;
}
else if (m_pSslLayer)
{
Send(_T("534 Authentication type already set to SSL"));
break;
}
args.MakeUpper();
if (args == _T("GSSAPI"))
{
if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_USEGSS))
{
Send(_T("502 GSSAPI authentication not implemented"));
break;
}
m_pGssLayer = new CAsyncGssSocketLayer;
BOOL res = AddLayer(m_pGssLayer);
if (res)
{
res = m_pGssLayer->InitGSS(FALSE, (BOOL)m_pOwner->m_pOptions->GetOptionVal(OPTION_GSSPROMPTPASSWORD));
if (!res)
SendStatus(_T("Unable to init GSS"), 1);
}
if (!res)
{
RemoveAllLayers();
delete m_pGssLayer;
m_pGssLayer = NULL;
Send(_T("431 Could not initialize GSSAPI libraries"));
break;
}
Send(_T("334 Using authentication type GSSAPI; ADAT must follow"));
}
else if (args == _T("SSL") || args == _T("TLS"))
{
if (m_pSslLayer)
{
Send(_T("503 Already using SSL/TLS"));
break;
}
if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_ENABLESSL) || !m_pOwner->m_pOptions->GetOptionVal(OPTION_ALLOWEXPLICITSSL))
{
Send(_T("502 SSL/TLS authentication not allowed"));
break;
}
m_pSslLayer = new CAsyncSslSocketLayer;
BOOL res = AddLayer(m_pSslLayer);
if (res)
{
CString error;
#ifdef _UNICODE
int res = m_pSslLayer->SetCertKeyFile(ConvToLocal(m_pOwner->m_pOptions->GetOption(OPTION_SSLCERTFILE)), ConvToLocal(m_pOwner->m_pOptions->GetOption(OPTION_SSLKEYFILE)), ConvToLocal(m_pOwner->m_pOptions->GetOption(OPTION_SSLKEYPASS)), &error);
#else
int res = m_pSslLayer->SetCertKeyFile(m_pOwner->m_pOptions->GetOption(OPTION_SSLCERTFILE), m_pOwner->m_pOptions->GetOption(OPTION_SSLKEYFILE), m_pOwner->m_pOptions->GetOption(OPTION_SSLKEYPASS), &error);
#endif
if (res == SSL_FAILURE_LOADDLLS)
SendStatus(_T("Failed to load SSL libraries"), 1);
else if (res == SSL_FAILURE_INITSSL)
SendStatus(_T("Failed to initialize SSL libraries"), 1);
else if (res == SSL_FAILURE_VERIFYCERT)
{
if (error != _T(""))
SendStatus(error, 1);
else
SendStatus(_T("Failed to set certificate and private key"), 1);
}
if (res)
{
RemoveAllLayers();
delete m_pSslLayer;
m_pSslLayer = NULL;
Send(_T("431 Could not initialize SSL connection"));
break;
}
}
if (res)
{
int code = m_pSslLayer->InitSSLConnection(false);
if (code == SSL_FAILURE_LOADDLLS)
SendStatus(_T("Failed to load SSL libraries"), 1);
else if (code == SSL_FAILURE_INITSSL)
SendStatus(_T("Failed to initialize SSL library"), 1);
res = (code == 0);
}
if (res)
{
if (args == _T("SSL"))
{
SendStatus(_T("234 Using authentication type SSL"), 3);
static const char* reply = "234 Using authentication type SSL\r\n";
const int len = strlen(reply);
res = (m_pSslLayer->SendRaw(reply, len) == len);
}
else // TLS
{
SendStatus(_T("234 Using authentication type TLS"), 3);
static const char* reply = "234 Using authentication type TLS\r\n";
const int len = strlen(reply);
res = (m_pSslLayer->SendRaw(reply, len) == len);
}
}
if (!res)
{
RemoveAllLayers();
delete m_pSslLayer;
m_pSslLayer = NULL;
Send(_T("431 Could not initialize SSL connection"));
str.Format(_T("226 Transfer OK, unfortunately compression did increase the transfer size by %I64d bytes to %I64d bytes (%I64d.%02I64d%%)"), zlibBytesOut - zlibBytesIn, zlibBytesOut, percent / 100, percent % 100);
Send(str);
}
}
else if (mode == TRANSFERMODE_RECEIVE && zlibBytesIn && zlibBytesOut)
str.Format(_T("226 Transfer OK, unfortunately compression did increase the transfer size by %I64d bytes to %I64d bytes (%I64d.%02I64d%%)"), zlibBytesIn - zlibBytesOut, zlibBytesIn, percent / 100, percent % 100);
Send(str);
}
}
else
Send(_T("226 Transfer OK"));
}
else if (status==1)
Send(_T("426 Connection closed; transfer aborted."));